#include "user.h"
#include "unistd.h"
extern "C"{

void user_level_printf(char* str)
{
	long error = 0;

	__asm__	__volatile__	(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_1(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_1:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_putstring),"D"(str)
                    :"memory");	

   

}


uint64_t open(char* str,int64_t mode){


    long error = 0;
	
	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_2(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_2:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_OPEN),"D"(str),"S"(mode) 
                    :"memory");	

	// LOG_ERROR("error:number:%d",error);
  

}


uint64_t close(uint64_t fd){


    long error = 0;
	
	// register int fd asm("r15") = 0;

	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_3(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_3:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_CLOSE),"D"(fd)
                    :"memory");	

  
}


uint64_t read(uint64_t fd,uint8_t* buffer,uint64_t bytes){


    long error = 0;
	
	// register int fd asm("r15") = 0;
    
	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_4(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_4:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_READ),"D"(fd),"S"(buffer),"d"(bytes)
                    :"memory");	

  
}

uint64_t write(uint64_t fd,uint8_t* buffer,uint64_t bytes){


    long error = 0;
	
	// register int fd asm("r15") = 0;

	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_5(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_5:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_WRITE),"D"(fd),"S"(buffer),"d"(bytes)
                    :"memory");	

  
}


uint64_t lseek(uint64_t fd,uint64_t offset,uint64_t origin){


    long error = 0;
	
	// register int fd asm("r15") = 0;

	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_6(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_6:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_LSEEK),"D"(fd),"S"(offset),"d"(origin)
                    :"memory");	

  
}


void* brk(uint64_t size){


    long error = 0;
	
	// register int fd asm("r15") = 0;

	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_7(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_7:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_BRK),"D"(size)
                    :"memory");	

}

void* reboot(uint64_t cmd,void* arg){


    long error = 0;
	
	// register int fd asm("r15") = 0;

	__asm__	__volatile__(	\
                    "pushq %%r10 \n\t" \
                    "pushq %%r11 \n\t" \
                    "leaq	sysexit_return_address_8(%%rip),	%%r10	\n\t"
					"movq	%%rsp,	%%r11		\n\t"
					"sysenter			\n\t"
					"sysexit_return_address_8:	\n\t"
                    "xchgq %%rdx,%%r10 \n\t" \
                    "xchgq %%rcx,%%r11 \n\t" \
                    "popq %%r11 \n\t" \
                    "popq %%r10 \n\t" \
					:"=a"(error)
                    :"0"(__NR_REBOOT),"D"(cmd),"S"(arg)
                    :"memory");	

}

}


